#include "ASMInstruction.hpp"
#include "CodeGen.hpp"
#include "Module.hpp"

#include <iostream>
#include <memory>
#include <unordered_map>

// 主函数声明：将高级语言翻译为目标架构汇编
void translate_main(CodeGen *codegen);

int main() {
    // 初始化编译器模块和代码生成器
    auto *module = new Module();
    auto *codegen = new CodeGen(module);

    // 指定后续生成的汇编代码属于.text段（代码段）
    codegen->append_inst(".text", ASMInstruction::Atrribute);

    // 执行实际的代码翻译工作
    translate_main(codegen);

    // 输出生成的汇编代码
    std::cout << codegen->print();
    
    // 清理资源
    delete codegen;
    delete module;
    return 0;
}

// RISC-V条件分支和比较操作实现
void translate_main(CodeGen *codegen) {
    // 符号表：记录变量在栈帧中的偏移位置
    std::unordered_map<std::string, int> offset_map;

    /* ============== 函数声明部分 ============== */
    codegen->append_inst(".globl main", ASMInstruction::Atrribute);  // 全局可见符号
    codegen->append_inst(".type main, @function", ASMInstruction::Atrribute); // 函数类型标识

    /* ============== 函数入口点 ============== */
    codegen->append_inst("main", ASMInstruction::Label);  // 函数入口标签

    /* ============== 序言部分 (Prologue) ============== */
    // 分配32字节栈空间（包含保存寄存器和局部变量的空间）
    codegen->append_inst("addi sp, sp, -32");
    // 保存返回地址寄存器(ra)到栈中
    codegen->append_inst("sd ra, 24(sp)");
    // 保存旧的帧指针(s0)
    codegen->append_inst("sd s0, 16(sp)");
    // 设置新的帧指针(s0 = sp + 32)
    codegen->append_inst("addi s0, sp, 32");

    /* ============== 代码主体部分 ============== */
    codegen->append_inst(".Lmain_entry", ASMInstruction::Label);  // 主代码段标签

    /* 整数比较操作 (5 > 1) */
    offset_map["%op0"] = -24;  // 比较结果存储在s0-24位置
    codegen->append_inst("li t0, 5");          // 加载立即数5
    codegen->append_inst("li t1, 1");          // 加载立即数1
    codegen->append_inst("sgt t2, t0, t1");    // 有符号大于比较
    codegen->append_inst("sw t2, -24(s0)");    // 存储比较结果

    /* 布尔值到整型的零扩展 */
    offset_map["%op1"] = -28;  // 转换结果存储在s0-28位置
    codegen->append_inst("lw t0, -24(s0)");    // 加载比较结果
    codegen->append_inst("andi t0, t0, 1");    // 确保只有最低位有效
    codegen->append_inst("sw t0, -28(s0)");    // 存储转换结果

    /* 条件判断（检查%op1是否不等于0） */
    offset_map["%op2"] = -32;  // 判断结果存储在s0-32位置
    codegen->append_inst("lw t0, -28(s0)");    // 加载转换结果
    codegen->append_inst("snez t0, t0");       // 不等于0比较
    codegen->append_inst("sw t0, -32(s0)");    // 存储判断结果

    /* 条件分支指令 */
    codegen->append_inst("lw t0, -32(s0)");    // 加载判断结果
    codegen->append_inst("bnez t0, .Lmain_label3"); // 条件为真跳转
    codegen->append_inst("j .Lmain_label4");        // 条件为假跳转

    /* 分支目标1：返回233 */
    codegen->append_inst(".Lmain_label3", ASMInstruction::Label);
    codegen->append_inst("li a0, 233");  // 设置返回值233
    codegen->append_inst("j .Lmain_exit"); // 跳转到公共退出点

    /* 分支目标2：返回0 */
    codegen->append_inst(".Lmain_label4", ASMInstruction::Label);
    codegen->append_inst("li a0, 0");    // 设置返回值0
    codegen->append_inst("j .Lmain_exit"); // 跳转到公共退出点

    /* ============== 收尾部分 (Epilogue) ============== */
    codegen->append_inst(".Lmain_exit", ASMInstruction::Label);
    // 恢复返回地址寄存器(ra)
    codegen->append_inst("ld ra, 24(sp)");
    // 恢复旧的帧指针(s0)
    codegen->append_inst("ld s0, 16(sp)");
    // 释放栈空间（32字节）
    codegen->append_inst("addi sp, sp, 32");
    // 函数返回（跳转到ra寄存器指定的地址）
    codegen->append_inst("jr ra");
}
